package com.hddf.project.auth.service;

import java.util.HashMap;
import java.util.Map;

import org.hibernate.Session;
import org.kommii.common_utils.DateTime_Utils;
import org.kommii.common_utils.Token_Generator;
import org.kommii.encryption.AESHandler;
import org.kommii.encryption.HexHandler;
import org.kommii.encryption.MD5Handler;
import org.kommii.mysql_conn_pool.SessionProvider;

import com.hddf.project.auth.dao.UserDao;
import com.hddf.project.auth.dao.UserDao_MongoDB;
import com.hddf.project.auth.dao_impl.UserDaoImpl;
import com.hddf.project.auth.dao_impl.UserDaoImpl_MongoDB;
import com.hddf.project.auth.pojos.User;
import com.kommii.mongodb_utils.Mongodb_ConnPools;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;

public class WebLoginService {
	
	private static WebLoginService login_service = null;
	private static UserDao user_dao = null;
	private static UserDao_MongoDB user_dao_mongodb = null;
	//令牌有效时间 单位是 秒
	private static final long webtoken_lifetime = 3600;//60*60
	static {
		if(login_service==null){
			login_service = new WebLoginService();
		}
		if(user_dao==null){
			user_dao = new UserDaoImpl();
		}
		if(user_dao_mongodb==null){
			user_dao_mongodb = new UserDaoImpl_MongoDB();
		}
	}
	
	public static WebLoginService getInstance(){
		return login_service;
	}
	
	
	/**
	 * 登陆成功的话返回token 并且更新令牌(token) , 不成功返回fail 或者 exception
	 * @param username
	 * @param passwd
	 * @return
	 */
	public String login(String username,String passwd,String aeskey){
		Session s = null;
		DBCollection coll  = null;
		String password = null;
		User u = null;
		int user_id = 0; 
		try{
			coll = Mongodb_ConnPools.getMongoDB_Coll(User.mongodb_collection_name);
			u = user_dao_mongodb.getUserByName(username, coll);
			if(u==null){
				s = SessionProvider.getSession();
				u = user_dao.getUserByName(username, s);
				SessionProvider.commitSession(s);
				if(null!=u){
					user_dao_mongodb.save(u, coll);
				}else{
					return username+" 用户名不存在,请检查用户名!";
				}
			}
			
			if(null!=u){
				user_id = u.getId();
				password = u.getPassword();
			}
			
			String temp = MD5Handler.encrypt(passwd); 
			if(temp.equals(password)){
				long webtoken_deadline = DateTime_Utils.getCurrentSeconds() + webtoken_lifetime;
				String web_token = Token_Generator.getUUID_Token();
				BasicDBObject obj = new BasicDBObject();
				obj.put("user_id", user_id);
				obj.put("aes_key", aeskey);
				obj.put("webtoken_lifetime", webtoken_deadline);
				obj.put("web_token",web_token);
				boolean rs = user_dao_mongodb.addWebTokenAndAESKey(obj,coll);
				if(rs)
					return web_token;
				else
					return "fail";
			}else{
				return "fail";
			}
		}catch(Exception e){
			e.printStackTrace();
			SessionProvider.rollback(s);
			return "exception";
		}
	}
	
	/**
	 * 退出 将 web_token 清空, aes_key 清空 webtoken_lifetime 清零
	 * @param web_token
	 */
	public boolean logout(BasicDBObject obj){
		DBCollection coll  = null;
		try{
			coll = Mongodb_ConnPools.getMongoDB_Coll(User.mongodb_collection_name);
			boolean rs = user_dao_mongodb.addWebTokenAndAESKey(obj, coll);
			if(rs)
				return true;
			else
				return false;
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * 检验token 是否过期,如果没过期返回 User 对象
	 * @param web_token
	 * @return
	 */
	public Map<String,Object> checkWebToken(String web_token,String time){
		DBCollection coll  = null;
		//CookieService cs = CookieService.getInstance();
		Map<String,Object> map = new HashMap<String,Object>();
		String msg = "";
		try{
			coll = Mongodb_ConnPools.getMongoDB_Coll(User.mongodb_collection_name);
			DBObject obj =  user_dao_mongodb.getSimpleUserByWebToken(web_token, coll);
			System.out.println("obj: "+ obj);
			if(null!=obj){
				int isopen = (Integer)obj.get("isopen");
				String  name = (String)obj.get("username");
				if(0==isopen){
					msg = name+" 用户已经被管理员锁定,暂时不能进入系统";
					map.put("msg", msg);
					return map;
				}
			}
			if(null!=obj){
				String aes_key = (String)obj.get("aes_key");
				time = HexHandler.toStringHex(time);
				String str = AESHandler.decrypt(aes_key, time);
				long t = 0;
				try{
					t = Integer.decode(str);
				}catch(Exception e){
					t = -1;
				}
				if(t==-1){
					msg = "密钥错误,请重新登陆";
					map.put("msg", msg);
					return map;
				}/*else{
					long current = DateTime_Utils.getCurrentSeconds();
					if((current - t)>120 || (current - t)<-120){
						msg = "密钥超时,请重新操作;核对您计算机上的时间,务必与北京时间相同";
						map.put("msg", msg);
						return map;
					}
				}*/
				
				long webtoken_deadline = (Long)obj.get("webtoken_lifetime");
				long current = DateTime_Utils.getCurrentSeconds();
				if((current - webtoken_deadline)>=0){
					msg = "令牌超时,请重新登陆";
					map.put("msg", msg);
					return map;
				}else{
					//DBObject temp =  user_dao_mongodb.getUserByWebToken(web_token, coll);
					String webtoken = Token_Generator.getUUID_Token();
					obj.put("webtoken_lifetime",current+webtoken_lifetime);
					obj.put("web_token", webtoken);
					user_dao_mongodb.updateWebToken(obj, coll);
					User u = new User();
					u.toUserObject(obj);
					map.put("msg", msg);
					map.put("u", u);
					map.put("web_token",webtoken);
					return map;
				}
			}else{
				msg = "令牌错误,请重新登陆";
				map.put("msg", msg);
				return map;
			}
		}catch(Exception e){
			e.printStackTrace();
			msg = "令牌错误,请重新登陆";
			map.put("msg", msg);
			return map;
		}
		
	}

}
